﻿using System;
using System.Windows.Forms;
using BMS.BL;
using System.Configuration;
using System.Collections.Generic;
using log4net;
using System.ComponentModel;

namespace RTEvents
{
    public partial class frmManager : Form
    {
        private bool canEntry = false;

        private bool isConnected = false;//the boolean value identifies whether the device is connected

        private BiometricProcess business;

        private int tryAgain = 1;

        private readonly ILog log = LogManager.GetLogger(typeof(frmManager));

        public frmManager()
        {
            InitializeComponent();

            business = new BiometricProcess();

            log.Debug("Inicializando el proceso");

            txtIP.Text = ConfigurationManager.AppSettings["IP"];

            txtPort.Text = ConfigurationManager.AppSettings["Port"];

            log.Debug("Carga de la configuración completa");

            this.backgroundWorker1.DoWork += DoWork;

            this.backgroundWorker1.RunWorkerCompleted += RunWorkerCompleted;

            this.backgroundWorker1.RunWorkerAsync();

            Connect();

        }

        public zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass();

        #region Communication

        private void Connect()
        {
            if (txtIP.Text.Trim() == "" || txtPort.Text.Trim() == "")
            {
                MessageBox.Show("IP y Puerto no pueden ser nulos", "Error");
                return;
            }
            int idwErrorCode = 0;

            isConnected = axCZKEM1.Connect_Net(txtIP.Text, Convert.ToInt32(txtPort.Text));

            if (isConnected == true)
            {
                lblState.Text = "Estado: Conectado";

                    
                {
                    this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx);
                }

                notifyIcon1.BalloonTipText += string.Concat("IP: ", this.txtIP.Text, Environment.NewLine, "Estado: ", lblState.Text);
            }
            else
            {
                axCZKEM1.GetLastError(ref idwErrorCode);

                MessageBox.Show("Deshabilitada la conexión hacia el dispositivo biométrico, Código del error=" + idwErrorCode.ToString(), "Error");

                notifyIcon1.BalloonTipText += string.Concat("IP: ", this.txtIP.Text, Environment.NewLine, "Estado: ", lblState.Text);
            }
            Cursor = Cursors.Default;
        }

        #endregion

        #region Eventos

        private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode)
        {
            List<string> messages = null;

            try
            {
                log.Debug(string.Format("Verificando el ingreso para el usuario: {0}", sEnrollNumber));

                canEntry = business.CanEntry(sEnrollNumber, out messages);

                txtDetails.Text += "Inicio OnAttTrasactionEx";
                txtDetails.Text += "...Identificador del usuario:" + sEnrollNumber;
                txtDetails.Text += "...Es inválido?:" + iIsInValid.ToString();
                txtDetails.Text += "...Estado:" + iAttState.ToString();
                txtDetails.Text += "...Método de verificación:" + iVerifyMethod.ToString();
                txtDetails.Text += "...Código de trabajo:" + iWorkCode.ToString();//the difference between the event OnAttTransaction and OnAttTransactionEx
                txtDetails.Text += "...Fecha y hora del evento:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                if (canEntry)
                {
                    log.Debug(string.Format("Realizando la apertura de la puerta para el usuario: {0}", sEnrollNumber));

                    axCZKEM1.ACUnlock(int.Parse(ConfigurationManager.AppSettings["MachineNumber"].ToString()), int.Parse(ConfigurationManager.AppSettings["Delay"].ToString()));

                    business.CreateEntryRegister(sEnrollNumber);
                }
                else
                {
                    log.Debug(string.Format("El usuario: {0} por configuración no tiene acceso, por favor valide la programación de turnos.", sEnrollNumber));
                }
            }
            catch (Exception exc)
            {
                log.Error(string.Concat("Error verificando la información del usuario: ", sEnrollNumber, " Mensaje retornado por el sistema: ", exc.ToString(), " Excepción interna: ", exc.StackTrace));
            }
        }


        private void frm_ResizeEvent(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                notifyIcon1.Visible = true;
                this.Hide();
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                notifyIcon1.Visible = false;
                this.Show();
            }
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            log.Debug(string.Concat("Reportando el estado del dispositivo: ", txtIP.Text));

            log.Debug(string.Concat("El dispositivo se encuentra conectado? ", isConnected ? "Si" : "No"));
            try
            {

                if (!isConnected)
                {
                    log.Debug("Validando la cantidad de reintentos configurada para iniciar reintentos");

                    if (tryAgain < int.Parse(ConfigurationManager.AppSettings["TotalTryAgain"].ToString()))
                    {
                        log.Debug(string.Concat("Realizando el reintento numero: ", tryAgain));

                        if (!axCZKEM1.Connect_Net(txtIP.Text, Convert.ToInt32(txtPort.Text)))
                        {
                            this.tryAgain++;
                        }
                        else
                        {
                            this.tryAgain = 1;
                        }
                    }
                    else
                    {
                        log.Debug(string.Concat("Enviando alarma por dispositivo inactivo despues de reintentos: ", txtIP.Text));

                        // Enviar mensaje para insertar en BD el estado del dispositivo
                        business.CreateDeviceRegister(txtIP.Text, ConfigurationManager.AppSettings["StateInactive"].ToString(), ConfigurationManager.AppSettings["StateInactiveObservations"].ToString());
                    }
                }
                else
                {
                    log.Debug(string.Concat("Enviando alarma por dispositivo inactivo: ", txtIP.Text));

                    // Enviar mensaje para insertar en BD el estado del dispositivo
                    business.CreateDeviceRegister(txtIP.Text, ConfigurationManager.AppSettings["StateActive"].ToString(), ConfigurationManager.AppSettings["StateActiveObservations"].ToString());
                }

            }
            catch (Exception exc)
            {
                log.Error(string.Concat("Se presentaron inconvenientes realizando la validacion del estado del dispositivo: ", exc.ToString()));
            }

            System.Threading.Thread.Sleep(int.Parse(ConfigurationManager.AppSettings["IntervalValidateProcessStatus"].ToString()));
        }

        private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            log.Debug(string.Concat("Se finaliza el reporte del estado del dispositivo: ", txtIP.Text));
        }

        #endregion

    }
}